package com.fbms.config.Interceptor;


import cn.hutool.core.bean.BeanUtil;
import com.fbms.common.utils.UserHolder;
import com.fbms.module.auth.Bean.LoginUserDTO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.fbms.common.constants.CacheConstants.LOGIN_TOKEN_KEY;
import static com.fbms.common.constants.Constants.TOKEN_EXPIRE;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;


/**
 * 类描述：拦截请求 做Token时间刷新
 *
 * @ClassName LoginInterceptor
 * @Author HappyBoy
 * @Date 2022-11-20 15:12
 **/
public class RefreshTokenInterceptor implements HandlerInterceptor {

    // @Autowired -- 无法使用 因为该类未被SpringBoot管理
    private StringRedisTemplate redisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 前置拦截
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler chosen handler to execute, for type and/or instance evaluation
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader(AUTHORIZATION);
        if (StringUtils.isEmpty(token)) {
            return true;
        }

        // 获取token  CacheConstants.LOGIN_TOKEN_KEY
        String tokenKey = LOGIN_TOKEN_KEY + token;
//        // 根据token 获取用户信息
        Map<Object, Object> userInfoMap = redisTemplate.opsForHash().entries(tokenKey);
//        // 判断是否存在
        if(userInfoMap.isEmpty()){
            return true;
        }

        // 将userMap 转为 userDTO
        LoginUserDTO userInfo = BeanUtil.fillBeanWithMap(userInfoMap, new LoginUserDTO(), false);
        // 存在 存储到Threadlocal中 放行
        UserHolder.saveUser(userInfo);

        // 刷新token有效期
        redisTemplate.expire(tokenKey, TOKEN_EXPIRE, TimeUnit.SECONDS);
        return true;
    }


    /**
     * 渲染之后 返回之前
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler the handler (or {@link HandlerMethod}) that started asynchronous
     * execution, for type and/or instance examination
     * @param ex any exception thrown on handler execution, if any; this does not
     * include exceptions that have been handled through an exception resolver
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 删除用户信息 防止内存溢出
        UserHolder.removeUser();
    }
}
